home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 December / PCWorld_2007-12_cd.bin / v cisle / htttrack / httrack-3.41-3.exe / {app} / src / htsjava.c < prev    next >
C/C++ Source or Header  |  2007-02-03  |  13KB  |  494 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20.  
  21. Important notes:
  22.  
  23. - We hereby ask people using this source NOT to use it in purpose of grabbing
  24. emails addresses, or collecting any other private information on persons.
  25. This would disgrace our work, and spoil the many hours we spent on it.
  26.  
  27.  
  28. Please visit our Website: http://www.httrack.com
  29. */
  30.  
  31.  
  32. /* ------------------------------------------------------------ */
  33. /* File: Java classes parser                                    */
  34. /* Author: Yann Philippot                                       */
  35. /* ------------------------------------------------------------ */
  36.  
  37.  
  38. /* Version: Oct/2000 */
  39. /* Fixed: problems with class structure (10/2000) */
  40.  
  41. // htsjava.c - Parseur de classes java
  42.  
  43. #ifdef HAVE_CONFIG_H
  44. #include "config.h"
  45. #endif
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #if ( defined(_WIN32) ||defined(HAVE_SYS_TYPES_H) )
  50. #include <sys/types.h>
  51. #endif
  52. #ifdef HAVE_UNISTD_H
  53. #include <unistd.h>
  54. #endif
  55.  
  56. /* Standard httrack module includes */
  57. #include "httrack-library.h"
  58. #include "htsopt.h"
  59. #include "htsdefines.h"
  60.  
  61. /* Module structures */
  62. #include "htsmodules.h"
  63.  
  64. /* We link to libhttrack, we can use its functions */
  65. #include "httrack-library.h"
  66.  
  67. /* This file */
  68. #include "htsjava.h"
  69.  
  70. static int reverse_endian(void) {
  71.     int endian = 1;
  72.     return ( * ( (char*) &endian) == 1);
  73. }
  74.  
  75. /* big/little endian swap */
  76. #define hts_swap16(A) ( (((A) & 0xFF)<<8) | (((A) & 0xFF00)>>8) )
  77. #define hts_swap32(A) ( (( (hts_swap16(A)) & 0xFFFF)<<16) | (( (hts_swap16(A>>16)) & 0xFFFF)) )
  78.  
  79. /* Static definitions */
  80. static RESP_STRUCT readtable(htsmoduleStruct* str,FILE *fp,RESP_STRUCT,int*);
  81. static unsigned short int readshort(FILE *fp);
  82. static int tris(httrackp *opt,char*);
  83. static char * printname(char [1024],char [1024]);
  84.  
  85. // ** HTS_xx sinon pas pris par VC++
  86. #define HTS_CLASS  7
  87. #define HTS_FIELDREF  9
  88. #define HTS_METHODREF  10
  89. #define HTS_STRING  8
  90. #define HTS_INTEGER  3
  91. #define HTS_FLOAT  4
  92. #define HTS_LONG  5
  93. #define HTS_DOUBLE  6
  94. #define HTS_INTERFACE  11
  95. #define HTS_NAMEANDTYPE  12
  96. #define HTS_ASCIZ  1
  97. #define HTS_UNICODE  2
  98.  
  99. #define JAVADEBUG 0
  100.  
  101. static const char *libName = "htsjava";
  102.  
  103. #ifdef _WIN32
  104. #define strcasecmp(a,b) stricmp(a,b)
  105. #define strncasecmp(a,b,n) strnicmp(a,b,n)
  106. #endif
  107.  
  108. static int detect_mime(htsmoduleStruct* str) {
  109.   const char* savename = str->filename;
  110.   if (savename) {
  111.     int len = (int) strlen(savename);
  112.     if (len > 6 && strcasecmp(savename + len - 6,".class") == 0) {
  113.       return 1;
  114.     }
  115.   }
  116.   return 0;
  117. }
  118.  
  119. static int hts_detect_java(t_hts_callbackarg *carg, httrackp *opt,
  120.                            htsmoduleStruct* str) 
  121. {
  122.   /* Call parent functions if multiple callbacks are chained. */
  123.   if (CALLBACKARG_PREV_FUN(carg, detect) != NULL) {
  124.     if (CALLBACKARG_PREV_FUN(carg, detect)(CALLBACKARG_PREV_CARG(carg), opt, str)) {
  125.       return 1;  /* Found before us, let them have the priority */
  126.     }
  127.   }
  128.  
  129.   /* Check MIME */
  130.   if (detect_mime(str)) {
  131.     str->wrapper_name = libName;  /* Our ID */
  132.     return 1; /* Known format, we take it */
  133.   }
  134.  
  135.   return 0;   /* Unknown format */
  136. }
  137.  
  138. static off_t fsize(const char* s) {
  139.   FILE* fp;
  140.   fp=fopen(s,"rb");
  141.   if (fp!=NULL) {
  142.     off_t i;
  143.     fseek(fp,0,SEEK_END);
  144.     i = ftell(fp);
  145.     fclose(fp);
  146.     return i;
  147.   } else 
  148.     return -1;
  149. }
  150.  
  151. static int hts_parse_java(t_hts_callbackarg *carg, httrackp *opt,
  152.                           htsmoduleStruct* str)
  153. {
  154.   /* The wrapper_name memebr has changed: not for us anymore */
  155.   if (str->wrapper_name == NULL || strcmp(str->wrapper_name, libName) != 0) {
  156.     /* Call parent functions if multiple callbacks are chained. */
  157.     if (CALLBACKARG_PREV_FUN(carg, parse) != NULL) {
  158.       return CALLBACKARG_PREV_FUN(carg, parse)(CALLBACKARG_PREV_CARG(carg), opt, str);
  159.     }
  160.     strcpy(str->err_msg, "unexpected error: bad wrapper_name and no previous wrapper");
  161.     return 0;     /* Unexpected error */
  162.   } else {
  163.     if (detect_mime(str)) {
  164.  
  165.       /* (Legacy code) */
  166.       char catbuff[CATBUFF_SIZE];
  167.       FILE *fpout;
  168.       JAVA_HEADER header;
  169.       RESP_STRUCT *tab;
  170.       const char* file = str->filename;
  171.  
  172.       str->relativeToHtmlLink = 1;
  173.  
  174. #if JAVADEBUG
  175.       printf("fopen\n");
  176. #endif
  177.       if ((fpout = fopen(fconv(catbuff, file), "r+b")) == NULL)
  178.       {
  179.         //fprintf(stderr, "Cannot open input file.\n");
  180.         sprintf(str->err_msg,"Unable to open file %s",file);
  181.         return 0;   // une erreur..
  182.       }
  183.  
  184. #if JAVADEBUG
  185.       printf("fread\n");
  186. #endif
  187.       //if (fread(&header,1,sizeof(JAVA_HEADER),fpout) != sizeof(JAVA_HEADER)) {   // pas complet..
  188.       if (fread(&header,1,10,fpout) != 10) {   // pas complet..
  189.         fclose(fpout);
  190.         sprintf(str->err_msg,"File header too small (file len = "LLintP")",(LLint)fsize(file));
  191.         return 0;
  192.       }
  193.  
  194. #if JAVADEBUG
  195.       printf("header\n");
  196. #endif
  197.       // tester en tΩte
  198.       if (reverse_endian()) {
  199.         header.magic = hts_swap32(header.magic);
  200.         header.count = hts_swap16(header.count); 
  201.       }
  202.       if(header.magic!=0xCAFEBABE) {
  203.         sprintf(str->err_msg,"non java file");
  204.         if (fpout) { fclose(fpout); fpout=NULL; }
  205.         return 0;
  206.       }
  207.  
  208.       tab =(RESP_STRUCT*)calloc(header.count,sizeof(RESP_STRUCT));
  209.       if (!tab) {
  210.         sprintf(str->err_msg,"Unable to alloc %d bytes",(int)sizeof(RESP_STRUCT));
  211.         if (fpout) { fclose(fpout); fpout=NULL; }
  212.         return 0;    // erreur..
  213.       }
  214.  
  215. #if JAVADEBUG
  216.       printf("calchead\n");
  217. #endif
  218.       {
  219.         int i;
  220.  
  221.         for (i = 1; i < header.count; i++) {
  222.           int err=0;  // ++    
  223.           tab[i]=readtable(str,fpout,tab[i],&err);
  224.           if (!err) {
  225.             if ((tab[i].type == HTS_LONG) ||(tab[i].type == HTS_DOUBLE)) i++;  //2 element si double ou float
  226.           } else {    // ++ une erreur est survenue!
  227.             if (strnotempty(str->err_msg)==0)
  228.               strcpy(str->err_msg,"Internal readtable error");
  229.             free(tab);
  230.             if (fpout) { fclose(fpout); fpout=NULL; }
  231.             return 0;
  232.           }
  233.         }
  234.  
  235.       }
  236.  
  237.  
  238. #if JAVADEBUG
  239.       printf("addfiles\n");
  240. #endif
  241.       {
  242.         unsigned int acess;
  243.         unsigned int Class;
  244.         unsigned int SClass;
  245.         int i;
  246.         acess = readshort(fpout);
  247.         Class = readshort(fpout);
  248.         SClass = readshort(fpout);
  249.  
  250.         for (i = 1; i <header.count; i++) {
  251.  
  252.           if (tab[i].type == HTS_CLASS) {
  253.  
  254.             if ((tab[i].index1<header.count) && (tab[i].index1>=0)) {
  255.  
  256.  
  257.               if((tab[i].index1!=SClass) && (tab[i].index1!=Class) && (tab[tab[i].index1].name[0]!='[')) {
  258.  
  259.                 if(!strstr(tab[tab[i].index1].name,"java/")) {
  260.                   char BIGSTK tempo[1024];
  261.                   tempo[0]='\0';
  262.  
  263.                   sprintf(tempo,"%s.class",tab[tab[i].index1].name);
  264. #if JAVADEBUG
  265.                   printf("add %s\n",tempo);
  266. #endif
  267.                   if (tab[tab[i].index1].file_position >= 0)
  268.                     str->addLink(str,tempo);  /* tab[tab[i].index1].file_position */
  269.                 }
  270.  
  271.               }
  272.             } else { 
  273.               i=header.count;  // exit 
  274.             }
  275.           }
  276.  
  277.         }
  278.       }
  279.  
  280.  
  281. #if JAVADEBUG
  282.       printf("end\n");
  283. #endif
  284.       free(tab);
  285.       if (fpout) { fclose(fpout); fpout=NULL; }
  286.       return 1;
  287.  
  288.     } else {
  289.       strcpy(str->err_msg, "bad MIME type");
  290.     }
  291.   }
  292.   return 0;   /* Error */
  293. }
  294.  
  295. /*
  296. module entry point 
  297. */
  298. EXTERNAL_FUNCTION int hts_plug(httrackp *opt, const char* argv);
  299. EXTERNAL_FUNCTION int hts_plug(httrackp *opt, const char* argv) {
  300.   /* Plug callback functions */
  301.   CHAIN_FUNCTION(opt, detect, hts_detect_java, NULL);
  302.   CHAIN_FUNCTION(opt, parse, hts_parse_java, NULL);
  303.  
  304.   return 1;  /* success */
  305. }
  306.  
  307. // error: !=0 si erreur fatale
  308. static  RESP_STRUCT readtable(htsmoduleStruct* str, 
  309.                               FILE *fp, RESP_STRUCT trans, int* error)
  310. {
  311.     char rname[1024];
  312.   unsigned short int length;
  313.   int j;
  314.   *error = 0;  // pas d'erreur
  315.   trans.file_position=-1;
  316.   trans.type = (int)(unsigned char)fgetc(fp);
  317.   switch (trans.type) {
  318.   case HTS_CLASS:
  319.     strcpy(trans.name,"Class");
  320.     trans.index1 = readshort(fp);
  321.     break;
  322.     
  323.   case HTS_FIELDREF:
  324.     strcpy(trans.name,"Field Reference");
  325.     trans.index1 = readshort(fp);
  326.     readshort(fp);
  327.     break;
  328.     
  329.   case HTS_METHODREF:
  330.     strcpy(trans.name,"Method Reference");
  331.     trans.index1 = readshort(fp);
  332.     readshort(fp);
  333.     break;
  334.     
  335.   case HTS_INTERFACE:
  336.     strcpy(trans.name,"Interface Method Reference");
  337.     trans.index1 =readshort(fp);
  338.     readshort(fp);
  339.     break;
  340.   case HTS_NAMEANDTYPE:
  341.     strcpy(trans.name,"Name and Type");
  342.     trans.index1 = readshort(fp);
  343.     readshort(fp);
  344.     break;
  345.     
  346.   case HTS_STRING:                // CONSTANT_String
  347.     strcpy(trans.name,"String");
  348.     trans.index1 = readshort(fp);
  349.     break;
  350.     
  351.   case HTS_INTEGER:
  352.     strcpy(trans.name,"Integer");
  353.     for(j=0;j<4;j++) fgetc(fp);
  354.     break;
  355.     
  356.   case HTS_FLOAT:
  357.     strcpy(trans.name,"Float");
  358.     for(j=0;j<4;j++) fgetc(fp);
  359.     break;
  360.     
  361.   case HTS_LONG:
  362.     strcpy(trans.name,"Long");
  363.     for(j=0;j<8;j++) fgetc(fp);
  364.     break;
  365.   case HTS_DOUBLE:
  366.     strcpy(trans.name,"Double");
  367.     for(j=0;j<8;j++) fgetc(fp);
  368.     break;
  369.     
  370.   case HTS_ASCIZ:
  371.   case HTS_UNICODE:
  372.     
  373.     if (trans.type == HTS_ASCIZ)
  374.       strcpy(trans.name,"HTS_ASCIZ");
  375.     else
  376.       strcpy(trans.name,"HTS_UNICODE");
  377.     
  378.     {
  379.       char BIGSTK buffer[1024]; 
  380.       char *p;
  381.       
  382.       p=&buffer[0];
  383.  
  384.       //fflush(fp); 
  385.       trans.file_position=ftell(fp);
  386.       length = readshort(fp);
  387.       if (length<HTS_URLMAXSIZE) {
  388.         // while ((length > 0) && (length<500)) {
  389.         while (length > 0) {
  390.           *p++ =fgetc(fp);
  391.           
  392.           length--;
  393.         }
  394.         *p='\0';
  395.         
  396.         //#if JDEBUG
  397.         //      if(tris(buffer)==1) printf("%s\n ",buffer);
  398.         //      if(tris(buffer)==2)  printf("%s\n ",printname(buffer));
  399.         //#endif
  400.                 if(tris(str->opt,buffer)==1)  str->addLink(str, buffer);       /* trans.file_position */
  401.         else if(tris(str->opt,buffer)==2)  str->addLink(str, printname(rname,buffer));
  402.  
  403.         strcpy(trans.name,buffer);
  404.       } else {    // gros pb
  405.         while ( (length > 0) && (!feof(fp))) {
  406.           fgetc(fp);
  407.           length--;
  408.         }
  409.         if (!feof(fp)) {
  410.           trans.type=-1;
  411.         } else {
  412.           sprintf(str->err_msg,"Internal stucture error (ASCII)");
  413.           *error = 1;
  414.         }
  415.         return(trans);
  416.       }
  417.     }
  418.     break;
  419.   default:
  420.     // printf("Type inconnue\n");
  421.     // on arrΩte tout 
  422.     sprintf(str->err_msg,"Internal structure unknown (type %d)",trans.type);
  423.     *error = 1;
  424.     return(trans);
  425.     break;
  426.   }  
  427.   return(trans);
  428. }
  429.  
  430.  
  431. static unsigned short int readshort(FILE *fp)
  432. {
  433.   unsigned short int valint;
  434.   fread(&valint,sizeof(valint),1,fp);
  435.  
  436.   if (reverse_endian())
  437.     return hts_swap16(valint);
  438.   else
  439.     return valint;
  440.   
  441. }
  442.  
  443. static int tris(httrackp *opt,char * buffer)
  444. {
  445.     char catbuff[CATBUFF_SIZE];
  446.   //
  447.   // Java
  448.   if((buffer[0]=='[') && buffer[1]=='L' && (!strstr(buffer,"java/")) ) 
  449.     return 2;
  450.   if (strstr(buffer,".gif") || strstr(buffer,".jpg") || strstr(buffer,".jpeg") || strstr(buffer,".au") ) 
  451.     return 1;
  452.   // Ajouts R.X: test type
  453.   // Autres fichiers
  454.   {
  455.     char type[256];
  456.     type[0]='\0';
  457.     get_httptype(opt,type,buffer,0);
  458.     if (strnotempty(type))     // type reconnu!
  459.       return 1;
  460.     // ajout RX 05/2001
  461.     else if (is_dyntype(get_ext(catbuff, buffer)))   // asp,cgi...
  462.       return 1;
  463.   }
  464.   return 0;
  465. }
  466.  
  467. static char * printname(char rname[1024], char name[1024])
  468. {
  469.   char *p;
  470.   char *p1;
  471.   int j;
  472.   rname[0]='\0';
  473.   //
  474.  
  475.   p=&name[0];
  476.   
  477.   if(*p!='[')  return "";
  478.   p+=2;
  479.   //rname=(char*)calloct(strlen(name)+8,sizeof(char));
  480.   p1=rname;
  481.   for (j = 0; j < (int) strlen(name); j++,p++) {
  482.     if (*p == '/') *p1='.'; 
  483.     if (*p==';'){*p1='\0';
  484.     strcat(rname,".class");
  485.     return (rname);}
  486.     else *p1=*p;
  487.     p1++;
  488.   }
  489.   p1-=3;
  490.   *p1='\0';
  491.   return (rname);
  492.   
  493. }
  494.